/**
 * Copyright (C) 2010 Cloudfarming <info@cloudfarming.nl>
 *
 * Licensed under the Eclipse Public License - v 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.eclipse.org/legal/epl-v10.html
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package nl.cloudfarming.client.planning.tactical;

import java.awt.Dialog;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import net.miginfocom.swing.MigLayout;
import nl.cloudfarming.client.logging.AppLogFactory;
import nl.cloudfarming.client.logging.AppLogger;
import nl.cloudfarming.client.model.Field;
import nl.cloudfarming.client.model.ProductionUnit;
import nl.cloudfarming.client.model.ProductionUnitAction;
import nl.cloudfarming.client.model.PartField;
import nl.cloudfarming.client.model.FieldPlan;
import nl.cloudfarming.client.planning.PlanAction;
import nl.cloudfarming.client.planning.PlanEventKey;
import nl.cloudfarming.eventbus.BaseGuiEventProducer;
import org.jdesktop.swingx.JXDatePicker;
import org.jdesktop.swingx.JXPanel;
import org.openide.DialogDescriptor;
import org.openide.DialogDisplayer;
import org.openide.util.Lookup;
import org.openide.util.NbBundle;
import org.openide.util.Utilities;

/**
 * Plan a new ProductionUnit action.
 * @author Timon Veenstra
 */
public class PlanProductionUnitAction extends PlanAction implements ProductionUnitAction {

    private final String DISPLAY_NAME = NbBundle.getMessage(this.getClass(), "field_plan.plan_production_unit_action.name.name");
    private static final String SUMMARY_DIALOG_TITLE = NbBundle.getMessage(LinkProductionUnitToFieldAction.class, "field_plan.plan_production_unit_action.summary_dialog.title");    
     
    private JTextField cropDescriptionTextfield = new JTextField(25);
    private JTextField nameTextField = new JTextField(25);
    private JXDatePicker startDatePicker = new JXDatePicker();
    private JXDatePicker endDatePicker = new JXDatePicker();
    private Dialog dlg;
    //Use via getService();
    private TacticalPlanningService service;
    private JList availableFieldsList;

    private static final AppLogger LOG = AppLogFactory.getLogger(PlanProductionUnitAction.class);
    
        
    public PlanProductionUnitAction() {
        putValue(NAME, DISPLAY_NAME);
        service = Lookup.getDefault().lookup(TacticalPlanningService.class);
    }

    protected TacticalPlanningService getService() {
        if (service == null) {
            service = new TacticalPlanningService();
        }
        return service;
    }
        
    /**
     * Crop en field
     * @param e Actionevent e
     */
    @Override
    public void actionPerformed(ActionEvent e) {

        //
        // populate the panel with the information about what the user is about to save
        //
        JXPanel panel = new JXPanel(new MigLayout("wrap 2"));

        panel.add(new JLabel(NbBundle.getMessage(this.getClass(), "field_plan.plan_production_unit_action.name.name_textfield")));
        panel.add(nameTextField);

        panel.add(new JLabel(NbBundle.getMessage(this.getClass(), "field_plan.plan_production_unit_action.name.crop")));
        panel.add(cropDescriptionTextfield);

        panel.add(new JLabel(NbBundle.getMessage(this.getClass(), "field_plan.plan_production_unit_action.name.startDate")));
        panel.add(startDatePicker);

        panel.add(new JLabel(NbBundle.getMessage(this.getClass(), "field_plan.plan_production_unit_action.name.endDate")));
        panel.add(endDatePicker);

        panel.add(new JLabel("Fields"));
        panel.add(getFieldScrollPane());


        //
        // create the dialog and add the ok and cancel buttons
        //
        DialogDescriptor dd = new DialogDescriptor(panel, DISPLAY_NAME);
        dd.setOptions(new Object[]{getOkButton(), getCancelButton()});
        dlg = DialogDisplayer.getDefault().createDialog(dd);
        dlg.setVisible(true);
    }

    /**
     * Create scrollpane containing all Fields.
     * 
     * @return Scrollpane containing all Fields
     */
    private JScrollPane getFieldScrollPane() {
        
        JScrollPane scrollPane = new JScrollPane();
        List<Field> fields = service.findAllFields();
        availableFieldsList = new JList(fields.toArray());

        scrollPane.setViewportView(availableFieldsList);
        return scrollPane;
    }

    /**
     * creates the dialog ok button
     *
     * @return
     */
    private JButton getOkButton() {
        JButton jButtonOK = new JButton();
        jButtonOK.setText(NbBundle.getMessage(this.getClass(), "field_plan.plan_production_unit_action.name.ok"));
        jButtonOK.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                okButtonActionPerformed();

            }
        });
        return jButtonOK;
    }
    
    /**
     * Method will be called when OK-button is pressed
     */
    private void okButtonActionPerformed(){
        dlg.setVisible(false);
        String cropDescription = cropDescriptionTextfield.getText();
        String name = nameTextField.getText();
        Date startDate = startDatePicker.getDate();
        Date endDate = endDatePicker.getDate();
        
        
        // Get current selected fieldplan from lookup
        FieldPlan fieldPlan = Utilities.actionsGlobalContext().lookup(FieldPlan.class);

        assert(fieldPlan != null); // Should never happen, action can only be called on fieldplan.
        
        // Build PU
        ProductionUnit.Builder productionUnitBuilder = new ProductionUnit.Builder().setCrop(cropDescription).setFieldPlan(fieldPlan).setName(name).setStartDate(startDate).setEndDate(endDate);
        ProductionUnit productionUnit = getService().createProductionUnit(productionUnitBuilder);

        
        StringBuilder fieldsSb = new StringBuilder();
        
        // Loop through selected fields. Create partfield for each, link PU to each.
        for(Object selectedField : availableFieldsList.getSelectedValues()){
            if(selectedField instanceof Field){
                Field field = (Field) selectedField ;
                fieldsSb.append("- ");
                fieldsSb.append("(");
                fieldsSb.append(field.getId());
                fieldsSb.append(") ");
                fieldsSb.append(field.getName());
                fieldsSb.append("\n");
                        
                PartField partField = Field.createPartFieldFrom(field, productionUnit);
                
                getService().createPartField(partField);
                
                // Add partfield to PU
                productionUnit.getPartFields().add(partField);
                productionUnit.setFieldPlan(fieldPlan);
            }
        }
        // TODO: PU has a fieldplan, fieldplan has PU's (2-way?)
        fieldPlan.getProductionUnits().add(productionUnit);        
        
        // Created production unit {0} ({1}) on fields [{2}] starting on {3} and ending on {4}    
        String summary_dialog_text = NbBundle.getMessage(LinkProductionUnitToFieldAction.class, "field_plan.plan_production_unit_action.summary_dialog.text", productionUnit.getName(), productionUnit.getCrop(), fieldsSb.toString(), productionUnit.getStartDate(), productionUnit.getEndDate());    
        JOptionPane.showMessageDialog (null, summary_dialog_text, SUMMARY_DIALOG_TITLE, JOptionPane.INFORMATION_MESSAGE);
        LOG.info(summary_dialog_text);
               
    }

    /**
     * creates the dialog cancel button
     * @return
     */
    private JButton getCancelButton() {
        JButton jButtonCancel = new JButton();
        jButtonCancel.setText(NbBundle.getMessage(this.getClass(), "field_plan.plan_production_unit_action.name.cancel"));
        jButtonCancel.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                dlg.setVisible(false);
            }
        });
        return jButtonCancel;
    }
}
